package com.nineclock.system.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.nineclock.common.entity.PageResult;
import com.nineclock.common.enums.ResponseEnum;
import com.nineclock.common.exception.NcException;
import com.nineclock.common.utils.BeanHelper;
import com.nineclock.common.utils.CurrentUserHolder;
import com.nineclock.system.dto.SysCompanyUserDTO;
import com.nineclock.system.dto.SysRoleDTO;
import com.nineclock.system.listener.ExcelMemberListener;
import com.nineclock.system.mapper.*;
import com.nineclock.system.pojo.*;
import com.nineclock.system.service.SysCompanyUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Service
@Slf4j
public class SysCompanyUserServiceImpl implements SysCompanyUserService {

    @Autowired
    SysCompanyUserMapper userMapper;
    @Autowired
    SysDepartmentMapper departmentMapper;


    @Override
    public List<SysCompanyUserDTO> queryCompanyMemberList() {

        LambdaQueryWrapper<SysCompanyUser> queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.eq(SysCompanyUser::getCompanyId, CurrentUserHolder.get().getCompanyId());
//        查询状态的员工为正常状态的员工
        queryWrapper.eq(SysCompanyUser::getEnable,1);

        List<SysCompanyUser> companyUserList = userMapper.selectList(queryWrapper);
        if(CollectionUtil.isEmpty(companyUserList)){
            throw new NcException(ResponseEnum.USER_NOT_FOUND);
        }

        return BeanHelper.copyWithCollection(companyUserList,SysCompanyUserDTO.class);
    }

    @Override
    public PageResult<SysCompanyUserDTO> queryMembers(Integer page, Integer pageSize, String keyword, Long departmentId) {
//        查询当前部门下的所有的子部门的id集合(包含当前部门id ，子部门id)
//        分页查询
        List<Long> departmentIds=new ArrayList<>();

        if (departmentId!=0){
            departmentIds.add(departmentId);
        }

        this.queryChildDepartMent(departmentIds,departmentId);

//        模糊查询
        LambdaQueryWrapper<SysCompanyUser> userLambdaQueryWrapper=new LambdaQueryWrapper<>();
        userLambdaQueryWrapper.eq(SysCompanyUser::getCompanyId,CurrentUserHolder.get().getCompanyId());
        userLambdaQueryWrapper.in(SysCompanyUser::getDepartmentId,departmentIds);
        if (StrUtil.isNotEmpty(keyword)){
            userLambdaQueryWrapper.and(queryWrapper->{
                queryWrapper.like(SysCompanyUser::getMobile,keyword).or()
                        .like(SysCompanyUser::getUserName,keyword).or()
                        .like(SysCompanyUser::getWorkNumber,keyword);
            });
        }
        Page<SysCompanyUser> userPage=new Page<>(page,pageSize);
//        分页查询
        userPage = userMapper.selectPage(userPage, userLambdaQueryWrapper);
        List<SysCompanyUser> records = userPage.getRecords();
        List<SysCompanyUserDTO> companyUserDTOS = BeanHelper.copyWithCollection(records, SysCompanyUserDTO.class);
        return new PageResult<>(userPage.getTotal(),userPage.getPages(),companyUserDTOS);
    }

    public void queryChildDepartMent(List<Long> departmentIds,Long parentId){
        LambdaQueryWrapper<SysDepartment> queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.eq(SysDepartment::getCompanyId,CurrentUserHolder.get().getCompanyId());
        queryWrapper.eq(SysDepartment::getParentId,parentId);
        List<SysDepartment> departments = departmentMapper.selectList(queryWrapper);
        if (CollectionUtil.isNotEmpty(departments)){
            Set<Long> ids=new HashSet<>();
            for (SysDepartment department : departments) {
                Long id = department.getId();
                boolean b = ids.add(id);
            }
            departmentIds.addAll(ids);
            for (Long id : ids) {
                this.queryChildDepartMent(departmentIds,id);
            }
        }
    }

//    TODO EasyExcel批量导入文件
    @Override
    public void importData(MultipartFile excelFile) throws IOException {
        //1. 健壮性判断
        if(excelFile == null){
            throw new NcException(ResponseEnum.UPLOAD_FILE_NOT_FOUND);
        }

        //2. 解析Excel文件 , 封装数据 , 持久化数据
        EasyExcel.read(excelFile.getInputStream(), ExcelMember.class, new ExcelMemberListener(this)).sheet(0).doRead();
    }

    @Autowired
    SysUserMapper sysUserMapper;
    @Autowired
    SysCompanyUserMapper sysCompanyUserMapper;
    @Autowired
    SysRoleMapper sysRoleMapper;
    @Autowired
    private SysCompanyUserRoleMapper sysCompanyUserRoleMapper;
    @Override
    public void handleParsedData(List<ExcelMember> memberList) {
        for (ExcelMember excelMember : memberList) {
//            1、保存用户数据
            SysUser sysUser=new SysUser();
//           判定系统用户手机号 , 邮箱是否已经被注册
            int count = sysUserMapper.checkEmailAndMobileCount(excelMember.getEmail(),excelMember.getMobile());
            if(count != 0){
                throw new NcException(ResponseEnum.USER_MOBILE_EMAIL_EXISTS);
            }
  //        判定企业用户工号是否被占用
            int worknumberCount = sysCompanyUserMapper.checkWorknumberCount(excelMember.getWorkNumber());
            if(worknumberCount != 0){
                throw new NcException(ResponseEnum.WROK_NUM_EXISTS);
            }

//          封装系统用户数据 , 对密码进行加密
            sysUser.setMobile(excelMember.getMobile());
            sysUser.setEmail(excelMember.getEmail());
            sysUser.setUsername(excelMember.getName());
            sysUser.setCreateTime(excelMember.getEntryTime());
            sysUser.setStatus(excelMember.getEnable().equals("可用")?(short)1:(short)0);
            sysUser.setPassword(new BCryptPasswordEncoder().encode("123456"));

            sysUserMapper.insert(sysUser);

            //2、保存CompanyUser员工数据
            SysCompanyUser companyUser = new SysCompanyUser();
            //2.1 组装员工的基本信息
            companyUser.setUserId(sysUser.getId());
            companyUser.setUserName(excelMember.getName());
            companyUser.setMobile(excelMember.getMobile());
            companyUser.setEmail(excelMember.getEmail());
            companyUser.setRemark(excelMember.getDesc());
            companyUser.setEnable(excelMember.getEnable().equals("可用")?(short)1:(short)0);
            companyUser.setPost(excelMember.getPosition());
            companyUser.setCompanyId(CurrentUserHolder.get().getCompanyId());
            companyUser.setCompanyName(CurrentUserHolder.get().getCompanyName());
            companyUser.setOfficeAddress(excelMember.getWorkAddr());
            companyUser.setTimeEntry(excelMember.getEntryTime());
            companyUser.setWorkNumber(excelMember.getWorkNumber());


            //2.2 组装员工的部门信息
            String departmentName = excelMember.getDepartmentName();
            if(StrUtil.isNotEmpty(departmentName)){
                LambdaQueryWrapper<SysDepartment> depQueryWrapper = new LambdaQueryWrapper<>();
                depQueryWrapper.eq(SysDepartment::getCompanyId, CurrentUserHolder.get().getCompanyId());
                depQueryWrapper.eq(SysDepartment::getName, departmentName);

                SysDepartment sysDepartment = departmentMapper.selectOne(depQueryWrapper);
                if(sysDepartment != null){
                    companyUser.setDepartmentId(sysDepartment.getId());
                    companyUser.setDepartmentName(departmentName);
                }
            }

            //2.3 保存企业员工
            sysCompanyUserMapper.insert(companyUser);


            //2.4 保存员工的角色信息
            String roleName = excelMember.getRoleName();
            if(StrUtil.isNotEmpty(roleName)){
                LambdaQueryWrapper<SysRole> roleQueryWrapper = new LambdaQueryWrapper<>();
                roleQueryWrapper.eq(SysRole::getRoleDesc, roleName);
                roleQueryWrapper.eq(SysRole::getCompanyId, CurrentUserHolder.get().getCompanyId());

                SysRole sysRole = sysRoleMapper.selectOne(roleQueryWrapper);
                if(sysRole != null){
                    SysCompanyUserRole companyUserRole = new SysCompanyUserRole();
                    companyUserRole.setCompanyId(CurrentUserHolder.get().getCompanyId());
                    companyUserRole.setCompanyUserId(companyUser.getId());
                    companyUserRole.setRoleId(sysRole.getId());

                    sysCompanyUserRoleMapper.insert(companyUserRole);
                }
            }
        }

    }

    @Override
    public Integer queryUserCountByDepartmentIds(List<Long> departmentIds) {

        //获取传递过来的部门及其所有的子部门
        List<Long> ids = new ArrayList<>();
        ids.addAll(departmentIds);

        for (Long departmentId : departmentIds) {
            this.queryChildDepartMent(ids, departmentId);
        }

        //组装条件查询用户数量
        LambdaQueryWrapper<SysCompanyUser> companyUserQueryWrapper = new LambdaQueryWrapper<>();
        companyUserQueryWrapper.in(SysCompanyUser::getDepartmentId , ids);
        companyUserQueryWrapper.eq(SysCompanyUser::getEnable, (short)1);

        return userMapper.selectCount(companyUserQueryWrapper);
    }

    @Override
    public SysCompanyUserDTO findCompanyUserByMobile(String mobile) {

        //参数校验
        if(StrUtil.isEmpty(mobile)){
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }

        //组装条件查询
        LambdaQueryWrapper<SysCompanyUser> userWrapper = new LambdaQueryWrapper<>();
        userWrapper.eq(SysCompanyUser::getMobile, mobile);

        SysCompanyUser sysCompanyUser = sysCompanyUserMapper.selectOne(userWrapper);

        return BeanHelper.copyProperties(sysCompanyUser, SysCompanyUserDTO.class);
    }

    @Override
    public List<SysCompanyUserDTO> queryCompanyUser(Long companyId, Long userId) {
        //健壮性的判断
        if(companyId == null && userId == null){
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }

        LambdaQueryWrapper<SysCompanyUser> companyUserQw = new LambdaQueryWrapper<>();
        //判断是否是有效的员工信息
        companyUserQw.eq(SysCompanyUser::getEnable, 1);
        if(userId != null){
            companyUserQw.eq(SysCompanyUser::getUserId, userId);
        }

        if(companyId != null){
            companyUserQw.eq(SysCompanyUser::getCompanyId, companyId);
        }

        List<SysCompanyUser> sysCompanyUsers = sysCompanyUserMapper.selectList(companyUserQw);

        //健壮性的判断
        if(CollectionUtil.isEmpty(sysCompanyUsers)){
            throw new NcException(ResponseEnum.USER_NOT_JOIN_COMPANY);
        }

        //转换为 dto对象
        List<SysCompanyUserDTO> companyUserDTOList = BeanHelper.copyWithCollection(sysCompanyUsers, SysCompanyUserDTO.class);

        //给每一个员工查询角色信息
        for (SysCompanyUserDTO companyUserDTO : companyUserDTOList) {
            //根据员工id查询关联的角色信息
            List<SysRole> roleList = sysRoleMapper.queryRolesByUserIdAndCompanyId(companyUserDTO.getId(), companyUserDTO.getCompanyId());

            if(CollectionUtil.isEmpty(roleList)){
                companyUserDTO.setRoles(new ArrayList<>());
            }else{
                companyUserDTO.setRoles(BeanHelper.copyWithCollection(roleList, SysRoleDTO.class));
            }
        }
        return companyUserDTOList;
    }
}
